import type {
  ElementHideConfig,
  ElementHideResult,
} from './types'
import { queryJQuery } from '../../lib/element_query'
import { InjectorType } from '../../lib/style_injector'
import { ToolKit } from '../../lib/utils/toolkit'
import {
  ElementSelectorDOMScopeType,
  VisibilitySettingsManager,
} from '../../types/constants'
import { ElementTag } from '../config/element_tag'
import { WebElement } from '../config/web_element'
import { ElementHideCssOperation, ElementHideOperationType } from './types'

/**
 * 检测元素隐藏规则
 * @returns 是否存在隐藏规则
 */
export function detectElementHideRules(): boolean {
  const webRules = WebElement.getInstance().getSelectors()
  const tagRules = ElementTag.getInstance().getSelectors()

  const hasWebHideRules = Object.values(webRules)
    .some(config => config.enable)
  const hasTagHideRules = Object.values(tagRules)
    .some(config => config.enable)

  return hasWebHideRules || hasTagHideRules || VisibilitySettingsManager.hasHideRules()
}

/**
 * 检查元素隐藏设置
 * @param options 元素隐藏配置
 * @returns 元素隐藏结果
 */
export function checkElementHideSettings(options: ElementHideConfig): ElementHideResult {
  const baseResult: ElementHideResult = {
    operationType: ElementHideOperationType.Skip,
    requiresCssInjection: false,
    isValid: false,
    reason: '',
  }

  if (!options.enable) {
    baseResult.reason = '元素隐藏功能未启用'
    return baseResult
  }

  // 策略1：事件驱动处理（优先级最高）
  if (options.hide && options.handler) {
    return {
      ...baseResult,
      operationType: ElementHideOperationType.EventDriven,
      isValid: true,
    }
  }
  // 策略2：动态元素处理（支持 CSS 注入处理）
  else if (options.hide && options.listen) {
    const result = {
      ...baseResult,
      operationType: ElementHideOperationType.Dynamic,
      isValid: true,
    }
    return handleElement(options, result)
  }
  // 策略3：取消动态监听
  else if (!options.hide && options.listen) {
    const result = {
      ...baseResult,
      operationType: ElementHideOperationType.DynamicCancellation,
      isValid: true,
    }
    return handleElement(options, result)
  }

  // 策略4：静态元素处理（默认策略，支持 CSS 注入处理）
  return handleElement(options, baseResult)
}

/**
 * 处理元素
 */
function handleElement(
  config: ElementHideConfig,
  baseResult: ElementHideResult,
): ElementHideResult {
  const { domScope, hostSelector, selector } = config
  const result = { ...baseResult, isValid: true }

  // 如果启用 CSS 注入
  if (config.useCssInjection) {
    result.requiresCssInjection = true
    result.cssOperation = config.hide ? ElementHideCssOperation.Inject : ElementHideCssOperation.Remove

    if (config.domScope === ElementSelectorDOMScopeType.Document) {
      result.injectorType = InjectorType.Standard
    }
    else if (config.domScope === ElementSelectorDOMScopeType.ShadowRoot) {
      // 动态元素在 Shadow Root 中需要转换为静态处理，因为 ElementCSSHandler 元素样式处理时本来就会轮询处理，与动态处理重复
      if (result.operationType === ElementHideOperationType.Dynamic) {
        result.operationType = ElementHideOperationType.Static
      }
      result.injectorType = InjectorType.Shadow
    }
    else if (config.domScope === ElementSelectorDOMScopeType.Iframe) {
      result.injectorType = InjectorType.Iframe
    }
    else if (config.domScope === ElementSelectorDOMScopeType.CrossFramework) {
      result.injectorType = InjectorType.CrossFramework
    }
  }

  // 如果元素存在，取消动态处理
  if (result.operationType === ElementHideOperationType.Dynamic || result.operationType === ElementHideOperationType.DynamicCancellation) {
    const $elements = queryJQuery(selector, { domScope, hostSelector })

    if (ToolKit.ui.element.hasElements($elements))
      result.operationType = ElementHideOperationType.Static
  }

  return result
}
